﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;

namespace SharePoint.Contrib.Extensions
{
    /// <summary>
    /// Extension methods for the SPEventReceiverDefinitionCollection class
    /// </summary>
    public static class SPEventReceiverDefinitionCollectionExtensions
    {
        /// <summary>
        /// Adds an event receiver to the collection.
        /// </summary>
        /// <typeparam name="T">Type (class) that has the receiver</typeparam>
        /// <param name="receiverType">Type of receiver</param>
        public static void Add<T>(this SPEventReceiverDefinitionCollection instance, SPEventReceiverType receiverType) where T : class
        {           
            
            var TypeDefinition = new
            {
                Assembly = AssemblyManager<T>.AssemblyFullName,
                Class = AssemblyManager<T>.TypeFullName
            };

            if (instance
                .Contains(receiver =>
                            receiver.Assembly == TypeDefinition.Assembly &&
                            receiver.Class == TypeDefinition.Class &&
                            receiver.Type == receiverType) == false)
            {
                instance.Add(receiverType, TypeDefinition.Assembly, TypeDefinition.Class);
            }
        }

        /// <summary>
        /// Removes an event receiver from the collection.
        /// </summary>
        /// <typeparam name="T">Type (class) that has the receiver</typeparam>
        /// <param name="receiverType">Type of receiver</param>
        /// <remarks>This uses the type name, assembly name, and receiver type to find the element to remove.</remarks>
        public static void Remove<T>(this SPEventReceiverDefinitionCollection instance, SPEventReceiverType receiverType) where T : class
        {

            var TypeDefinition = new
            {
                Assembly = AssemblyManager<T>.AssemblyFullName,
                Class = AssemblyManager<T>.TypeFullName
            };

            var query = from SPEventReceiverDefinition receiver in instance
                        where receiver.Assembly == TypeDefinition.Assembly &&
                              receiver.Class == TypeDefinition.Class &&
                              receiver.Type == receiverType
                        select receiver;

            SPEventReceiverDefinition result;

            if (query.Execute(out result))
            {
                result.Delete();
            }
        }

        /// <summary>
        /// Determines whether the specified SPEventReceiverDefinition can be found in the collection.
        /// </summary>
        /// <param name="func">The delegate to use to search</param>
        public static bool Contains(this SPEventReceiverDefinitionCollection instance, Func<SPEventReceiverDefinition, bool> match)
        {
            return instance
                    .Cast<SPEventReceiverDefinition>()
                    .Any(match);
        }

        /// <summary>
        /// Removes all the event receivers from the collection.
        /// </summary>
        public static void RemoveAll(this SPEventReceiverDefinitionCollection instance)
        {
            for (int i = 0; i < instance.Count; i++)
            {
                instance[i].Delete();
            }

        }
    }
}
